<!DOCTYPE html>
<html lang="en">
  <head>
    {% with title="Gradio Docs", url="https://gradio.app/docs", image="/assets/img/meta-image.png", description="Browse Gradio Documentation and Examples" %}
      {% include "templates/meta.html" %}
    {% endwith %}
    <link rel="stylesheet" href="/style.css">
    <link rel="stylesheet" href="/assets/prism.css">
  </head>
  <body>
    <div class="container mx-auto flex flex-wrap justify-between flex-row relative items-center px-4 py-5 gap-6 text-lg z-50">
      <div class="flex flex-row items-center">
        <a href="/">
          <img src="/assets/gradio.svg">
        </a>
        <div class="pl-2 pr-1 py-1 w-fit text-gray-600 font-semibold">
          <select id="toggle"
                  onchange="this.options[this.selectedIndex].value && (window.location = this.options[this.selectedIndex].value);"
                  class="form-select appearance-none block px-3 text-base font-normal text-gray-700 bg-white bg-clip-padding bg-no-repeat border border-solid border-gray-300 rounded-full transition ease-in-out m-0 focus:text-gray-700 focus:bg-white focus:border-blue-600 focus:outline-none w-max"
                  style="width: 135%; padding-top: 0.125rem; padding-bottom: 0.125rem">
            <option value="/docs" {% if version=='pip' %}selected{% endif %}>
              v{{ gradio_version }}
            </option>
            <option value="/docs/main" {% if version=='main' %}selected{% endif %}>
              main
            </option>
          </select>
        </div>
      </div>
      <svg class="h-8 w-8 lg:hidden"
           viewBox="-10 -10 20 20"
           onclick="document.querySelector(&quot;nav&quot;).classList.toggle(&quot;hidden&quot;),document.querySelector(&quot;nav&quot;).classList.toggle(&quot;flex&quot;)">
        <rect x="-7" y="-6" width="14" height="2"></rect>
        <rect x="-7" y="-1" width="14" height="2"></rect>
        <rect x="-7" y="4" width="14" height="2"></rect>
      </svg>
      <nav class="hidden w-full flex-col gap-3 lg:flex lg:w-auto lg:flex-row lg:gap-8">
        <a class="thin-link flex items-center gap-3" href="/getting_started"><span>⚡</span> <span>Quickstart</span>
      </a>
      <a class="thin-link flex items-center gap-3" href="/docs"><span>✍️</span> <span>Docs</span>
    </a>
    <a class="thin-link flex items-center gap-3" href="/guides"><span>💡</span> <span>Guides</span></a>
    <a class="thin-link flex items-center gap-3" href="/demos"><span>🎢</span> <span>Demos</span></a>
    <div class="group relative flex cursor-pointer items-center gap-3"
         onclick="document.querySelector(&quot;.help-menu&quot;).classList.toggle(&quot;flex&quot;),document.querySelector(&quot;.help-menu&quot;).classList.toggle(&quot;hidden&quot;)">
      <span>🖐</span> <span>Community</span>
      <svg class="h-4 w-4"
           xmlns="http://www.w3.org/2000/svg"
           viewBox="0 0 20 20">
        <path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"></path>
      </svg>
      <div class="help-menu absolute top-6 hidden w-52 flex-col bg-white shadow group-hover:flex sm:right-0">
        <a class="thin-link inline-block px-4 py-2 hover:bg-gray-100"
           href="https://github.com/gradio-app/gradio/issues/new/choose"
           target="_blank">File an Issue</a>
        <a class="thin-link inline-block px-4 py-2 hover:bg-gray-100"
           href="https://discuss.huggingface.co/c/gradio/26"
           target="_blank">Discuss</a>
        <a class="thin-link inline-block px-4 py-2 hover:bg-gray-100"
           target="_blank"
           href="https://discord.gg/feTf9x3ZSB">Discord</a>
        <a class="thin-link inline-block px-4 py-2 hover:bg-gray-100"
           target="_blank"
           href="https://gradio.curated.co/">Newsletter</a>
      </div>
    </div>
    <a class="thin-link flex items-center gap-3"
       href="https://github.com/gradio-app/gradio">
      <img src="/assets/img/github-black.svg" class="w-6">
    </a>
  </nav>
</div>
<main class="container mx-auto px-4 flex gap-4">
  <div class="navigation pb-4 h-screen leading-relaxed sticky top-0 text-md overflow-y-auto hidden lg:block rounded-t-xl bg-gradient-to-r from-white to-gray-50 overflow-x-clip"
       style="width: 16.666667%;
              min-width: 16.666667%;">
    <div class="w-full sticky top-0 bg-gradient-to-r from-white to-gray-50 z-10">
      <input id="search"
             type="search"
             class="w-4/5 m-4 rounded-md border-gray-200 focus:placeholder-transparent focus:shadow-none focus:border-orange-500 focus:ring-0"
             placeholder="Search ⌘-k / ctrl-k"
             autocomplete="off"
             onkeyup="search(this.value);"
             onsearch="search(this.value);"/>
    </div>
    <a class="link current-nav-link px-4 mb-2 block" href="#building_demos">Building Demos</a>
    <a class="thin-link px-4 block" href="#interface">Interface</a>
    <div class="sub-links hidden" hash="#interface">
      {% with obj=find_cls("Interface") %}
        {% if "fns" in obj and obj["fns"]|length %}
          {% for fn in obj["fns"] %}
            <a class="thinner-link px-4 pl-8 block"
               href="#interface-{{ fn['name'].lower()}}">{{ fn["name"] }}</a>
          {% endfor %}
        {% endif %}
      {% endwith %}
    </div>
    <a class="thin-link px-4 block" href="#flagging">Flagging</a>
    <div class="sub-links hidden" hash="#flagging">
      {% for flagging_callback in docs["flagging"] %}
        {% with obj=flagging_callback %}
          <a class="thinner-link px-4 pl-8 block" href="#{{ obj['name'].lower()}}">{{ obj["name"] }}</a>
        {% endwith %}
      {% endfor %}
    </div>
    <a class="thin-link px-4 block" href="#combining-interfaces">Combining Interfaces</a>
    <div class="sub-links hidden" hash="#combining-interfaces">
      <a class="thinner-link px-4 pl-8 block" href="#tabbedinterface">TabbedInterface</a>
      <a class="thinner-link px-4 pl-8 block" href="#parallel">Parallel</a>
      <a class="thinner-link px-4 pl-8 block" href="#series">Series</a>
    </div>
    <a class="thin-link px-4 block" href="#blocks">Blocks<sup class="text-orange-500">NEW</sup></a>
    <div class="sub-links hidden" hash="#blocks">
      {% with obj=find_cls("Blocks") %}
        {% if "fns" in obj and obj["fns"]|length %}
          {% for fn in obj["fns"] %}
            <a class="thinner-link px-4 pl-8 block"
               href="#blocks-{{ fn['name'].lower()}}">{{ fn["name"] }}</a>
          {% endfor %}
        {% endif %}
      {% endwith %}
    </div>
    <a class="thin-link px-4 block" href="#block-layouts">Block Layouts</a>
    <div class="sub-links hidden" hash="#block-layouts">
      {% for layout in docs["layout"] %}
        {% with obj=layout %}
          <a class="thinner-link px-4 pl-8 block" href="#{{ obj['name'].lower()}}">{{ obj["name"] }}</a>
        {% endwith %}
      {% endfor %}
    </div>
    <a class="link px-4 my-2 block" href="#components">Components</a>
    {% for component in docs["component"] %}
      <a class="px-4 block thin-link" href="#{{ component['name'].lower() }}">{{ component['name'] }}</a>
    {% endfor %}
    <a class="link px-4 my-2 block" href="#helpers">Helpers
      {% for component in docs["helpers"] %}
        <a class="px-4 block thin-link" href="#{{ component['name'].lower() }}">{{ component['name'] }}</a>
      {% endfor %}
      <a class="link px-4 my-2 block" href="#routes">Routes
        {% for component in docs["routes"] %}
          <a class="px-4 block thin-link" href="#{{ component['name'].lower() }}">{{ component['name'] }}</a>
        {% endfor %}
      </div>
      <div class="flex flex-col w-full min-w-full	lg:w-10/12 lg:min-w-0">
        <div>
          <p class="bg-gradient-to-r from-orange-100 to-orange-50 border border-orange-200 px-4 py-1 mr-2 rounded-full text-orange-800 mb-1 w-fit float-left">
            New to Gradio? Start here: <a class="link" href="/getting_started">Getting Started</a>
          </p>
          <p class="bg-gradient-to-r from-green-100 to-green-50 border border-green-200 px-4 py-1 rounded-full text-green-800 mb-1 w-fit float-left sm:float-right">
            See the <a class="link" href="/changelog">Release History</a>
          </p>
        </div>
        {% if version == 'main' %}
          <div class="bg-gray-100 border border-gray-200 text-gray-800 px-4 py-1 mr-2 mt-4 rounded-lg">
            <p class="my-2 text-lg">
              To install Gradio from the latest commit to the main branch, run the following command:
            </p>
            <div class="codeblock bg-gray-50">
              <pre class="language-bash" style="width: 97%"><code class="language-bash">pip install {{ gradio_wheel_url }}</code></pre>
            </div>
          </div>
        {% endif %}
        <section id="building_demos" class="pt-2 flex flex-col gap-10 mb-8">
          <section class="pt-2">
            <h2 class="text-4xl font-light mb-2 pt-2 text-orange-500"
                id="building-demos">
              Building Demos
            </h2>
            {% with obj=find_cls("Interface"), is_class=True, parent="gradio" %}
              {% include "docs/obj_doc_template.html" %}
            {% endwith %}
          </section>
          <section id="flagging" class="pt-2">
            <h3 class="text-4xl font-light my-4" id="flagging">
              Flagging
            </h3>
            <p class="mt-8 mb-12 text-lg">
              A Gradio Interface includes a "Flag" button that appears
              underneath the output. By default, clicking on the Flag button sends the input and output
              data back to the machine where the gradio demo is running, and saves it to a CSV log file.
              But this default behavior can be changed. To set what happens when the Flag button is clicked,
              you pass an instance of a subclass of <em>FlaggingCallback</em> to the <em>flagging_callback</em> parameter
              in the <em>Interface</em> constructor. You can use one of the <em>FlaggingCallback</em> subclasses
              that are listed below, or you can create your own, which lets you do whatever
              you want with the data that is being flagged.
            </p>
            <div class="flex flex-col gap-10">
              {% for flagging_callback in docs["flagging"] %}
                {% with obj=flagging_callback, is_class=True, parent="gradio" %}
                  {% include "docs/obj_doc_template.html" %}
                {% endwith %}
              {% endfor %}
            </div>
          </section>
          <section id="combining-interfaces" class="pt-2">
            <h3 class="text-4xl font-light my-4">
              Combining Interfaces
            </h3>
            <p class="mt-8 mb-12 text-lg">
              Once you have created several Interfaces, we provide several classes that let you
              start combining them together. For example, you can chain them in <em>Series</em>
              or compare their outputs in <em>Parallel</em> if the inputs and outputs match accordingly.
              You can also display arbitrary Interfaces together in a tabbed layout using <em>TabbedInterface</em>.
            </p>
            <div class="flex flex-col gap-10">
              {% with obj=find_cls("TabbedInterface"), parent="gradio" %}
                {% include "docs/obj_doc_template.html" %}
              {% endwith %}
              {% with obj=find_cls("Parallel"), is_class=True, parent="gradio" %}
                {% include "docs/obj_doc_template.html" %}
              {% endwith %}
              {% with obj=find_cls("Series"), is_class=True, parent="gradio" %}
                {% include "docs/obj_doc_template.html" %}
              {% endwith %}
            </div>
          </section>
          <section id="blocks" class="pt-2 mb-8">
            <div class="flex flex-col gap-10">
              {% with obj=find_cls("Blocks"), is_class=True, parent="gradio" %}
                {% include "docs/obj_doc_template.html" %}
              {% endwith %}
            </div>
          </section>
          <section id="block-layouts" class="pt-2 mb-8">
            <h3 class="text-3xl font-light my-4">
              Block Layouts
            </h3>
            <p class="mb-12">
              Customize the layout of your Blocks UI with the layout classes below.
            </p>
            <div class="flex flex-col gap-10">
              {% for layout in docs["layout"] %}
                {% with obj=layout, is_class=True, parent="gradio" %}
                  {% include "docs/obj_doc_template.html" %}
                {% endwith %}
              {% endfor %}
            </div>
          </section>
        </section>
        <section id="components" class="pt-2 flex flex-col gap-10 mb-8">
          <div>
            <h2 id="components-header"
                class="text-4xl font-light mb-2 pt-2 text-orange-500">
              Components
            </h2>
            <p class="mt-8 text-lg">
              Gradio includes pre-built components that can be used as
              inputs or outputs in your Interface or Blocks with a single line of code. Components
              include <em>preprocessing</em> steps that convert user data submitted through browser
              to something that be can used by a Python function, and <em>postprocessing</em>
              steps to convert values returned by a Python function into something that can be displayed in a browser.
            </p>
            <p class="mt-2 text-lg">
              Consider an example with three inputs (Textbox, Number, and Image) and two outputs
              (Number and Gallery), below is a diagram of what our preprocessing will send to the function and what
              our postprocessing will require from it.
            </p>
            <img src="/assets/img/dataflow.svg" class="mt-4">
            <p class="mt-2 text-lg">
              Components also come with certain events that they support. These are methods that are triggered with user actions.
              Below is a table showing which events are supported for each component. All events are also listed (with parameters) in the component's docs.  
            </p>
            <div class="max-h-96 overflow-y-scroll my-6">
            <table class="table-fixed w-full leading-loose">
              <thead class="text-center sticky top-0 ">
                <tr>
                    <th class="p-3 bg-white w-1/5"></th>
                    <th class="p-3 font-normal bg-white border-t border-l">Change</th>
                    <th class="p-3 font-normal bg-white border-t">Click</th>
                    <th class="p-3 font-normal bg-white border-t">Submit</th>
                    <th class="p-3 font-normal bg-white border-t">Edit</th>
                    <th class="p-3 font-normal bg-white border-t">Clear</th>
                    <th class="p-3 font-normal bg-white border-t">Play</th>
                    <th class="p-3 font-normal bg-white border-t">Pause</th>
                    <th class="p-3 font-normal bg-white border-t">Stream</th>
                    <th class="p-3 font-normal bg-white border-t">Blur</th>
                    <th class="p-3 font-normal bg-white border-t border-r">Upload</th>
                </tr>
              </thead>
              <tbody class=" rounded-lg bg-gray-50 border border-gray-100 overflow-hidden text-left align-top divide-y">
                {% for component in docs["component"] %}
                <tr class="group hover:bg-gray-200/60">
                  <td class="p-3 w-1/5 bg-white">
                    {{ component["name"] }}
                  </td>
                  {% for event in ordered_events %}
                    <td class="p-3 text-gray-700 break-words text-center">
                    {% if event.lower() in component["events-list"] %}
                      <p class="text-orange-500">&#10003;</p>
                    {% else %}
                      <p class="text-gray-300	">&#10005;</p>
                    {% endif %}
                    </td>
                  {% endfor %}
                </tr>
                {% endfor %}
              </tbody>
            </table>
          </div>
          {% for component in docs["component"] %}
            {% with obj=component, is_class=True, is_component=True, parent="gradio" %}
              {% include "docs/obj_doc_template.html" %}
            {% endwith %}
          {% endfor %}
        </section>
        <section id="helpers" class="pt-2 flex flex-col gap-10 mb-8">
          <div>
            <h2 id="helpers-header"
                class="text-4xl font-light mb-2 pt-2 text-orange-500">
              Helpers
            </h2>
            <p class="mt-8 text-lg">
              Gradio includes helper classes and methods that interact with existing components. The goal of these classes and methods is to help you
              add common functionality to your app without having to rewrite common functions.
            </p>
          </div>
          {% for component in docs["helpers"] %}
            {% with obj=component, is_class=True, parent="gradio" %}
              {% include "docs/obj_doc_template.html" %}
            {% endwith %}
          {% endfor %}
        </section>
        <section id="routes" class="pt-2 flex flex-col gap-10 mb-8">
          <div>
            <h2 id="routes-header"
                class="text-4xl font-light mb-2 pt-2 text-orange-500">
              Routes
            </h2>
            <p class="mt-8 text-lg">
              Gradio includes some helper functions for exposing and interacting with the FastAPI app
              used to run your demo.
            </p>
          </div>
          {% for component in docs["routes"] %}
            {% with obj=component, parent="gradio" %}
              {% include "docs/obj_doc_template.html" %}
            {% endwith %}
          {% endfor %}
        </section>
      </div>
    </main>
    <script>
      let isMobile = window.matchMedia("only screen and (max-width: 480px)").matches;

      function loadJS(FILE_URL) {
        let scriptEle = document.createElement("script");
        scriptEle.setAttribute("src", FILE_URL);
        scriptEle.setAttribute("type", "module");
        document.body.appendChild(scriptEle);
      }

      {% if version=='main' %}

      if (!isMobile) {
        loadJS('/assets/index.js');
      }

      {% else %}

      if (!isMobile) {
        loadJS('https://gradio.s3-us-west-2.amazonaws.com/{{ gradio_version }}/gradio.js');
      }

      {% endif %}
    </script>
    <script src="/assets/prism.js"></script>
    <script>
      window.__gradio_mode__ = "website";
    </script>
    {% include 'templates/footer.html' %}
    <script>{% include 'templates/guide-color.js' %}</script>
    <script>{% include 'templates/add_anchors.js' %}</script>
    <script>{% include 'templates/add_copy.js' %}</script>
    <script>
    const show_demo = (component, demo) => {
      document.querySelectorAll(`#${component} .demo-btn.selected-demo`).forEach(n => n.classList.remove('selected-demo'));
      document.querySelectorAll(`#${component} .demo-content`).forEach(n => n.classList.add('hidden'));
      document.querySelector(`#${component} .demo-btn[name=${demo}]`).classList.add('selected-demo');
      document.querySelectorAll(`#${component} .demo-content[name=${demo}]`).forEach(n => n.classList.remove('hidden'));
    }
    window.onclick = function(event) {
      if (event.target.classList.contains('demo-window')) {
        document.querySelectorAll('.demo-window').forEach(n => n.classList.add('hidden'));
      }
    }

    let mainNavLinks = document.querySelectorAll(".navigation a");
    window.addEventListener("scroll", event => {
      let fromTop = window.scrollY;
      mainNavLinks.forEach(link => {
        let section = document.querySelector(link.hash);
        if (
          section.offsetTop <= fromTop &&
          section.offsetTop + section.offsetHeight > fromTop
        ) {
          link.classList.add("current-nav-link");
        } else {
          link.classList.remove("current-nav-link");
        }
      });
    });

    let mainNavSubLinks = document.querySelectorAll(".navigation .sub-links");

    window.addEventListener("scroll", event => {
      let fromTop = window.scrollY;
      mainNavSubLinks.forEach(subLinkDiv => {
        let hash = subLinkDiv.getAttribute('hash');
        let section = document.querySelector(hash);

        if (
          section.offsetTop <= fromTop &&
          section.offsetTop + section.offsetHeight > fromTop
        ) {
          subLinkDiv.classList.remove("hidden");
        } else {
          if (document.querySelector("#search").value.length == 0) {
            subLinkDiv.classList.add("hidden");
          }
        }
      });
    });

    const search = query => {
      if (query.length > 0) {
        query = query.toLowerCase();

        mainNavSubLinks.forEach(subLinkDiv => { subLinkDiv.classList.remove("hidden"); })

        var filtered_links = Array.from(mainNavLinks).filter(link => link.hash.toLowerCase().includes(query))
        filtered_include_parent = Array.from(filtered_links);

        filtered_links.forEach(link => {
          if (link.parentElement.classList.contains("sub-links")) {
            let id = link.parentElement.getAttribute('hash');
            mainNavLinks.forEach(mainLink => {
              if (mainLink.hash == id) {
                filtered_include_parent.push(mainLink);
              }
            });
        };
        })
      } else {

        mainNavSubLinks.forEach(subLinkDiv => { subLinkDiv.classList.add("hidden"); })

        var filtered_include_parent = Array.from(mainNavLinks);
      }

      mainNavLinks.forEach(link => {
        if (filtered_include_parent.includes(link)) {
          link.classList.remove("hidden");
        } else {
          link.classList.add("hidden");
        }
      })
      }

      document.addEventListener('keydown', function (e) {
        if (e.key.toLowerCase() === 'k' && (e.metaKey || e.ctrlKey)) {
            e.preventDefault();
            document.getElementById('search').focus();
        }
        if (e.key == 'Escape') {
            document.getElementById('search').value = '';
            document.getElementById('search').blur();
            search('');
        }
      })

    </script>
  </body>
</html>
